package com.hcss.login.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.hcss.common.base.BaseClass;
import com.hcss.common.constant.ConfigConstants;
import com.hcss.common.context.MySessionContext;
import com.hcss.common.util.EmptyUtil;
import com.hcss.common.util.EncipherUtil;
import com.hcss.common.vo.ResultMsg;
import com.hcss.common.vo.Results;
import com.hcss.login.service.LoginService;
import com.hcss.qywechat.user.model.WQyUser;
import com.hcss.qywechat.user.model.vo.WQyUserVO;
import com.hcss.sys.menu.service.MenuService;
import com.hcss.sys.modulelog.constant.ModulelogConstants;
import com.hcss.sys.modulelog.model.HcSysModulelog;
import com.hcss.sys.modulelog.queue.ModuleLogServiceQueue;
import com.hcss.sys.version.model.vo.HcSysVersionVO;
import com.hcss.sys.version.service.HcSysVersionService;
import com.hcss.util.AjaxResult;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.security.NoSuchAlgorithmException;

/**
 * @描述: 登录controller
 * @作者: xuqian
 * @创建日期: 2018-12-13 18:52
 * @公司 浙江鸿程计算机系统有限公司
 */
@RestController
public class LoginController {
	@Autowired
	RedisTemplate redisTemplate;


	@Autowired
	private LoginService loginService;

	@Autowired
	private ConfigConstants configConstants;

	@Autowired
	private MenuService menuService;

	@Autowired
	private HcSysVersionService hcSysVersionService;

	@RequestMapping("/")
	public ModelAndView index( ) {
		ModelAndView mav=new ModelAndView( "/index" );

		WQyUser user=BaseClass.getSessionUser( );
		mav.addObject( "user",user );

		return mav;
	}

	@RequestMapping("/loginPage")
	public ModelAndView loginPage( ) {
		Object object=SecurityUtils.getSubject( ).getPrincipal( );
		// 获取版本信息
		HcSysVersionVO model=hcSysVersionService.getVersionInfo( );
		// 已登录直接跳转首页
		if(!EmptyUtil.isHaveEmpty( object )) {
			return new ModelAndView( "redirect:/" );
		}
		ModelAndView mav=new ModelAndView( "/login" );
		mav.addObject( "hcSysVersionVO",JSON.toJSONString( model,SerializerFeature.WriteNullStringAsEmpty ) );
		return mav;
	}

	/**
	 * pc端登录
	 *
	 * @param usercode
	 * @param password
	 * @return
	 */
	@GetMapping("/login")
	public AjaxResult login( String usercode,String password ) {
		MySessionContext myc= MySessionContext.getInstance();
		/**
		 * 校验用户的密码和账户的准确性和用户的有效性
		 *
		 */

		if(EmptyUtil.isHaveEmpty( usercode,password )) {
			return AjaxResult.getErrorResult( "用户名密码不能为空" );
		}

		WQyUserVO user=loginService.getUserByUserid( usercode );

		if(EmptyUtil.isHaveEmpty( user )) {
			return AjaxResult.getErrorResult( "用户不存在" );
		}
		UsernamePasswordToken token;
        /*try {
            token = new UsernamePasswordToken(usercode, EncipherUtil.md5(password));
        } catch (NoSuchAlgorithmException e) {
            return AjaxResult.getErrorResult("密码加密出错");
        }*/
		//20210104 by fangtao 前端MD5加密
		password=password.substring( 33,password.length( )-23 );
		token=new UsernamePasswordToken( usercode,password );

		Subject currentUser=SecurityUtils.getSubject( );
		try {
			currentUser.login( token );
		} catch(UnknownAccountException e) {
			return AjaxResult.getErrorResult( "账号不存在" );
		} catch(IncorrectCredentialsException e) {
			return AjaxResult.getErrorResult( "密码错误" );
		}


		//对当前用户的操作进行日志记录
		if(currentUser.isAuthenticated( )) {
			HcSysModulelog hcSysModulelog=new HcSysModulelog( );
			hcSysModulelog.setUserid( BaseClass.getSessionUserid( ) );
			hcSysModulelog.setModuleurl( ModulelogConstants.LOGIN_URL );
			hcSysModulelog.setModulename( ModulelogConstants.LOGIN );
			hcSysModulelog.setLogtype( ModulelogConstants.logType.LOGIN_LOG );
			ModuleLogServiceQueue.getInstance( ).put( hcSysModulelog );
/*			//获取sessionID，来确定登录的唯一性
            //获取session
            HttpSession session=BaseClass.getSession( );
			myc.addSession( session );
            //获取用户ID
			String userId=BaseClass.getSessionUser( ).getUserid( );
			//获取sessionId
			String sessionId=BaseClass.getSession( ).getId( );
			//从redis里面来获取以上的数据信息
			String oldSessionId=redisTemplate.opsForValue( ).get( userId );
			//如果结果为空或者不同直接返回结果则直接登录并且缓存当前信息
			if(EmptyUtil.isHaveEmpty( oldSessionId )) {
				//使用redis来进行缓存以上相关信息
				redisTemplate.opsForValue( ).set( userId,sessionId );
			}else {
				//相同的时候清除之前的session，直接登录新的
				HttpSession sess = myc.getSession(oldSessionId);
				//清除session
				sess.invalidate();
				redisTemplate.opsForValue( ).set( userId,sessionId );
			}*/
			redisTemplate.opsForValue().set( "operator",BaseClass.getSessionUserid() );
            return new AjaxResult( );
		}else {
			token.clear( );
			return AjaxResult.getErrorResult( "登录失败" );
		}
	}


	/**
	 * 移动端登录
	 *
	 * @param agentid 企业微信应用id
	 * @param code    网页授权用户code
	 * @return
	 */
	@GetMapping(value="/user/{AGENTID}/{CODE}")
	public AjaxResult login( HttpServletResponse response,
	                         @PathVariable("CODE") String code,@PathVariable("AGENTID") Long agentid ) {
		WQyUserVO user;
		if(configConstants.getWechat( ).isDebug( )) {
			user=BaseClass.getSessionUser( );
			JSONObject data=new JSONObject( );
			data.put( "userid",user.getUserid( ) );
			data.put( "name",user.getName( ) );
			data.put( "gender",user.getGender( ) );
			data.put( "avatar",user.getAvatar( ) );
			data.put( "roles",user.getRoles( ) );
			data.put( "menus",menuService.selectUserMobileUrl( user.getUserid( ) ) );
			return AjaxResult.getSuccessResult( data );
		}else {
			if(EmptyUtil.isHaveEmpty( code,agentid )) {
				return AjaxResult.getMissingParamResult( );
			}
			if(!loginService.checkAgentid( agentid )) {
				return AjaxResult.getErrorResult( "非法应用访问" );
			}

			ResultMsg resultMsg=loginService.getUserByCode( code,agentid );
			if(resultMsg.getState( )==Results.ERROR) {
				return AjaxResult.getErrorResult( resultMsg.getMsg( ) );
			}
			user=(WQyUserVO) resultMsg.getEntity( );
		}
		UsernamePasswordToken token=new UsernamePasswordToken( user.getUserid( ),user.getPassword( ) );

		Subject currentUser=SecurityUtils.getSubject( );
		try {
			currentUser.login( token );
		} catch(Exception e) {
			return AjaxResult.getErrorResult( "登录出错，请重新操作" );
		}

		if(currentUser.isAuthenticated( )) {
			JSONObject data=new JSONObject( );
			data.put( "userid",user.getUserid( ) );
			data.put( "name",user.getName( ) );
			data.put( "gender",user.getGender( ) );
			data.put( "avatar",user.getAvatar( ) );
			data.put( "roles",user.getRoles( ) );
			data.put( "menus",menuService.selectUserMobileUrl( user.getUserid( ) ) );
			return AjaxResult.getSuccessResult( data );
		}else {
			token.clear( );
			return AjaxResult.getErrorResult( "登录出错，请重新操作" );
		}
	}

	/**
	 * 退出登录
	 *
	 * @return
	 */
	@GetMapping(value="/logout")
	public AjaxResult logout( ) {
		WQyUser user=BaseClass.getSessionUser( );
		HcSysModulelog hcSysModulelog=new HcSysModulelog( );
		hcSysModulelog.setUserid( BaseClass.getSessionUserid( ) );
		if(user!=null) {
			loginService.clearLoginCache( user.getUserid( ) );
			//使用权限管理工具进行用户的退出，跳出登录，给出提示信息
			SecurityUtils.getSubject( ).logout( );
		}
		hcSysModulelog.setModuleurl( ModulelogConstants.LOGOUT_URL );
		hcSysModulelog.setModulename( ModulelogConstants.LOGOUT );
		hcSysModulelog.setLogtype( ModulelogConstants.logType.LOGOUT_LOG );
		ModuleLogServiceQueue.getInstance( ).put( hcSysModulelog );
		return new AjaxResult( );
	}

}
